package com.boyon.customer.service.customer.impl;

import java.util.List;

import org.hibernate.type.StringType;
import org.hibernate.type.Type;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.boyon.common.domain.UserSession;
import com.boyon.common.exection.BusinessException;
import com.boyon.common.session.SessionManager;
import com.boyon.common.status.AccountEnmu;
import com.boyon.common.status.AccountType;
import com.boyon.common.status.Constant;
import com.boyon.common.status.CustomerCategoryType;
import com.boyon.common.status.RelationType;
import com.boyon.common.tools.ObjectTool;
import com.boyon.common.tools.StringTool;
import com.boyon.customer.domain.CustomerData;
import com.boyon.customer.entity.AgentRelation;
import com.boyon.customer.entity.Customer;
import com.boyon.customer.entity.Finace;
import com.boyon.customer.service.customer.CustomerServiceInterface;
import com.boyon.domain.AccountData;
import com.boyon.hbm.criteria.OperationType;
import com.boyon.hbm.criteria.Param;
import com.boyon.hbm.criteria.Query;
import com.boyon.service.AbstractService;
import com.boyon.service.AccountProviderService;
import com.boyon.service.CodingProviderService;
import com.boyon.service.ConfigProviderService;

/**
 * ClassName:AgentService <br/>
 * Function: 代理商业务类. <br/>
 * Date: 2018年4月2日 下午9:58:21 <br/>
 * 
 * @author sunshulin
 * @version
 * @since JDK 1.8
 * @see
 */
@Service
public class AgentService extends AbstractService
		implements CustomerServiceInterface {

	@Autowired
	private CustomerService customerService;
	@Autowired
	@Qualifier(value = "codingProviderService")
	private CodingProviderService codingProviderService;
	@Autowired
	@Qualifier(value = "accountProviderService")
	private AccountProviderService accountProviderService;
	@Autowired
	@Qualifier(value = "configProviderService")
	private ConfigProviderService configProviderService;

	public Integer getType() {
		return CustomerCategoryType.dl.getVal();
	}

	/**
	 * 保存代理商档案资料.
	 * 
	 * @see com.boyon.customer.service.customer.CustomerServiceInterface#save(com.boyon.customer.domain.CustomerData)
	 */
	@Transactional
	public Long save(CustomerData customerData) {
		UserSession userSession = SessionManager.getUserSession();
		validatorRelationType(userSession);
		String customerNo = codingProviderService
				.createCoding(Constant.CODE_AGENT);
		customerData.setCustomerNo(customerNo);
		customerData.setCustomerCategory(CustomerCategoryType.dl.getVal());
		Long customerId = customerService.save(customerData);
		Long parentCustomerId = null;
		AgentRelation agentRelation = new AgentRelation();
		agentRelation.setCustomerId(customerId);
		if (userSession.getRelationType()
				.equals(RelationType.system.getVal())) {
			// 系统账号,可以选择任意层级代理
			parentCustomerId = customerData.getParentCustomerId();
		} else {
			// 代理账号添加
			parentCustomerId = userSession.getRelationId();
		}
		agentRelation.setParentCustomerId(parentCustomerId);
		if (parentCustomerId == null) {
			agentRelation.setQueryPath(customerNo);
		} else {
			AgentRelation parentAgentRelation = generalDao
					.get(AgentRelation.class, parentCustomerId);
			agentRelation.setQueryPath(
					parentAgentRelation.getQueryPath() + customerNo);
		}
		generalDao.saveOrUpdate(agentRelation);
		// 代理商创建生成账号信息
		AccountData accountData = new AccountData();
		accountData.setAccountNo(customerNo);
		accountData.setRelationType(AccountEnmu.agent.getVal());
		accountData.setRelationId(customerId);
		accountData.setAccountType(AccountType.manager.getVal());
		String configValue = configProviderService
				.getConfigByKey(Constant.AGENT);
		accountData.setRoleId(StringTool.converStringToLong(configValue));
		accountProviderService.createAccount(accountData);
		return customerId;
	}

	/**
	 * 编辑代理商资料.
	 * 
	 * @see com.boyon.customer.service.customer.CustomerServiceInterface#editor(com.boyon.customer.domain.CustomerData)
	 */
	@Transactional
	public Long editor(CustomerData customerData) {
		UserSession userSession = SessionManager.getUserSession();
		validatorRelationType(userSession);
		Long customerId = customerService.editor(customerData);
		return customerId;
	}

	/**
	 * 删除代理商资料.
	 * 
	 * @see com.boyon.customer.service.customer.CustomerServiceInterface#delete(java.lang.Long)
	 */
	@Transactional
	public Long delete(Long customerId) {
		UserSession userSession = SessionManager.getUserSession();
		validatorRelationType(userSession);
		if (userSession.getRelationType()
				.equals(RelationType.system.getVal())) {
			// 系统账号可以删除任意代理
			return customerService.delete(customerId);
		} else {
			AgentRelation agentRelation = generalDao.get(AgentRelation.class,
					customerId);
			if (agentRelation.getParentCustomerId() == null) {
				throw BusinessException.builder(0, "顶级代理不能删除");
			}
			if (agentRelation.getParentCustomerId()
					.equals(userSession.getRelationId())) {
				return customerService.delete(customerId);
			} else {
				throw BusinessException.builder(0, "代理账号只能删除直接代理");
			}
		}
	}

	/**
	 * 查找代理商资料.
	 * 
	 * @see com.boyon.customer.service.customer.CustomerServiceInterface#findByCustomerId(java.lang.Long)
	 */
	@Transactional(readOnly = true)
	public CustomerData findByCustomerId(Long customerId) {
		UserSession userSession = SessionManager.getUserSession();
		validatorRelationType(userSession);
		CustomerData data = customerService.findByCustomerId(customerId);
		Finace finace = generalDao.get(Finace.class, customerId);
		ObjectTool.copy(finace, data);
		AgentRelation agentRelation = generalDao.get(AgentRelation.class,
				customerId);
		if (agentRelation.getParentCustomerId() != null) {
			data.setParentCustomerId(agentRelation.getParentCustomerId());
			Customer parent = customerService.getCustomerByCustomerId(
					agentRelation.getParentCustomerId());
			data.setParentCustomerName(parent.getCustomerName());
		}
		return data;
	}

	/**
	 * 查询代理商资料列表.
	 * 
	 * @see com.boyon.customer.service.customer.CustomerServiceInterface#query(com.boyon.customer.domain.CustomerData)
	 */
	@Transactional(readOnly = true)
	public List<CustomerData> query(CustomerData data, Query query) {
		UserSession userSession = SessionManager.getUserSession();
		validatorRelationType(userSession);
		query.addParam(new Param<Integer>("customerCategory", OperationType.eq,
				CustomerCategoryType.dl.getVal()));
		customerService.addParam(query, data);
		if (userSession.getRelationType().equals(RelationType.agent.getVal())) {
			// 代理账号查询下级代理
			Long customerId = userSession.getRelationId();
			AgentRelation agentRelation = generalDao.get(AgentRelation.class,
					customerId);
			String path = agentRelation.getQueryPath();
			query.addParam(new Param<Long>("customerId", OperationType.nq,
					customerId));
			query.addParam(new Param<Object[]>(
					"this_.customer_id in (select a.customer_id from boyon_customer.base_agent_relation a where query_path like ?)",
					OperationType.sql, new Object[] { path + "%" },
					new Type[] { StringType.INSTANCE }));
		}
		return customerService.query(data, query);
	}

	/**
	 * 
	 * validatorRelationType:验证关联关系权限. <br/>
	 * 
	 * @author sunshulin
	 * @param userSession
	 * @since JDK 1.8
	 */
	private void validatorRelationType(UserSession userSession) {
		RelationType relationType = RelationType
				.getType(userSession.getRelationType());
		if (relationType == RelationType.system
				|| relationType == RelationType.agent) {

		} else {
			throw BusinessException.builder(0, "代理账号,系统账号可以访问");
		}
	}

	/**
	 * 
	 * 重置代理商密码.
	 * 
	 * @see com.boyon.customer.service.customer.CustomerServiceInterface#resetPass(java.lang.Long)
	 */
	@Transactional
	public void resetPass(Long customerId) {
		Customer customer = customerService.getCustomerByCustomerId(customerId);
		accountProviderService.resetPass(customer.getCustomerId(),
				AccountEnmu.agent.getVal());
	}

}
